11058. Погоня за бабочкой
В ясные летние дни Нюша любит
ловить бабочек на свежем воздухе. Но сегодня ей попалась особенно хитрая
бабочка: она залетела в лабиринт и попыталась скрыться там от Нюши.
Лабиринт состоит из n
комнат, пронумерованных от 1 до n, некоторые из которых соединены
коридорами. Известно, что между любыми двумя комнатами существует единственный
путь, проходящий только по коридорам. Иными словами, лабиринт представляет
собой дерево, состоящее из n вершин и n − 1 рёбер.
Вход в лабиринт находится в
комнате с номером 1. Листом называется любая комната, соединённая ровно с одной
другой комнатой и не совпадающая с корнем (комнатой номер 1). В каждом листе
расположен выход из лабиринта. Бабочка начинает свой полёт из комнаты номер 1 в
направлении одного из выходов. Она движется с постоянной скоростью, не
разворачивается, и каждую минуту пролетает один коридор, переходя в соседнюю
комнату. Все коридоры имеют одинаковую длину.
Чтобы поймать бабочку, Нюша
решила позвать на помощь несколько друзей. Изначально каждый из них может
занять любую из комнат с выходом. Как только бабочка начнёт движение от входа к
какому-либо выходу, друзья могут сразу же начать двигаться из своих комнат по
направлению ко входу. Они двигаются с той же скоростью, что и бабочка. Если
кто-либо из них встретит бабочку – будь то в комнате или на середине коридора –
она считается пойманной. Если же бабочка доберётся до выхода, не столкнувшись
ни с одним из друзей, она благополучно выберется на свободу.
Помогите Нюше определить
минимальное число друзей, необходимое для того, чтобы гарантированно поймать
бабочку, вне зависимости от того, к какому выходу она полетит.
Вход. Первая строка содержит одно целое число n (2 ≤ n ≤ 200000) – количество комнат в лабиринте.
Следующие n – 1 строк
описывают коридоры, соединяющие комнаты. В каждой из них записаны два целых
числа u и v (1 ≤ u, v ≤ n, u
≠ v) – номера комнат, соединённых коридором.
Гарантируется, что заданная
система коридоров образует дерево.
Выход. Выведите одно целое число – минимальное количество друзей, необходимое для того, чтобы гарантированно поймать
бабочку.
| Пример
  входа 1 | Пример
  выхода 1 | 
| 3 1 2 1 3 | 2 | 
|  |  | 
| Пример
  входа 2 | Пример
  выхода 2 | 
| 4 1 2 2 3 2 4 | 1 | 
графы –
поиск в глубину
Выполним
обход в глубину из вершины 1. Для каждой вершины вычислим два значения:
·       
d[v] – расстояние от вершины 1 до вершины v.
Если p – родитель v, то 
d[v]
= d[p] + 1
·       
h[v] – расстояние от вершины v до ближайшего листа в поддереве с корнем v.
Если to1,
to2, …, tok – сыновья вершины v, то
h[v]
= 1 + min(h[to1], h[to2], …, h[tok])
·       
Если v
– лист дерева, то положим h[v]
= 0.
Затем
запустим второй обход в глубину. В ходе этого обхода будем вычислять значение res[v] – минимальное количество друзей,
которых нужно разместить в некоторых из листьев поддерева с корнем в вершине v,
чтобы гарантированно поймать бабочку, при условии, что она выбрала это
поддерево.
Если h[v] ≤ d[v], то res[v] = 1. В этом случае достаточно разместить одного друга в листе с минимальной глубиной в
поддереве вершины v: он успеет дойти до вершины v не позже, чем
бабочка — из корня дерева.
В
противном случае, если to1,
to2, …, tok – сыновья вершины v, то
res[v]
= res[to1] + res[to2] + … +  res[tok]
Если
бабочка не будет поймана в самой вершине v, необходимо быть готовыми
перехватить её в любом из поддеревьев, исходящих из сыновей v. 
Искомым
ответом на задачу является значение res[1].
Пример
В
первом примере (на рисунке слева) требуются два друга, которых необходимо
разместить у двух выходов. Бабочка может полететь из вершины 1 либо в вершину
2, либо в вершину 3. В любом из этих случаев её перехватит один из друзей Нюши.

Во
втором примере (на рисунке справа) достаточно одного друга, которого можно
разместить в любом из двух выходов – вершине
3 или 4. За одну минуту бабочка долетит из вершины 1 до вершины 2. За это же
время друг доберётся до вершины 2 и поймает бабочку там.
Рассмотрим следующий пример. 
Для поимки бабочки Нюше понадобятся
три друга.

Реализация алгоритма
Объявим константу бесконечность и
рабочие массивы.
#define INF 2000000000
vector<vector<int>
> g;
vector<int> d, h, res;
Функция
dfs (v, p, cnt) выполняет обход в глубину,
начиная с вершины v, и возвращает значение h[v]. При этом p
– предок вершины v, а cnt – расстояние от вершины 1 до v.
В процессе обхода для каждой вершины v вычисляются значения d[v]
и h[v].
int dfs(int v, int p = -1, int cnt = 0)
{
Значение
cnt, равное расстоянию от вершины 1 до v, сохраняем в d[v].
  d[v] = cnt;
  int height = INF;
Перебираем всех сыновей вершины v.
Рассматриваем ребро v → to. Если to совпадает с предком v (to = p),
переходим к следующему сыну.
  for (int to : g[v])
    if (to !=
p) 
В переменной height
вычисляем значение
min(h[to1],
h[to2], …, h[tok]),
где to1,
to2, …, tok – сыновья вершины v.
      height = min(height, dfs(to, v, cnt + 1));
Если height = INF, значит вершина v
является листом, и следует установить h[v] = 0. В противном случае возвращаем 
h[v]
= 1 + min(h[to1], h[to2], …, h[tok])
  return h[v] =
(height == INF) ? 0 : 1 + height;
}
Функция
dfs2 (v, p) выполняет обход в глубину, начиная с
вершины v, и возвращает значение res[v].
Здесь p – предок вершины v.
int dfs2(int v, int p = -1)
{
  int s = 0;
Пусть to1,
to2, …, tok – сыновья вершины v. В переменной s
вычислим сумму:
res[to1]
+ res[to2] + … +  res[tok]
    if (to !=
p)
    {
     
dfs2(to, v);
      s +=
res[to];
    }
Если h[v] ≤ d[v], то достаточно одного друга, и res[v] = 1. Иначе
res[v]
= res[to1] + res[to2] + … +  res[tok] = s
  return res[v] = (h[v] <=
d[v]) ? 1 : s;
}
Основная
часть программы. Читаем входные данные. Строим граф.
scanf("%d", &n);
g.resize(n + 1);
for (i = 0; i < n - 1; i++)
{
  scanf("%d %d", &a, &b);
  g[a].push_back(b);
  g[b].push_back(a);
}
Инициализируем
массивы.
d.resize(n + 1);
h.resize(n + 1);
res.resize(n + 1);
Запускаем
два обхода в глубину. Первый обход для каждой вершины v вычисляет
значения d[v] и h[v].
dfs(1);
dfs2(1);
Выводим
ответ – минимальное количество друзей, необходимое
для поимки бабочки.
printf("%lld\n", res[1]);